package com.rc.common.util;


import org.apache.commons.codec.binary.Hex;

import java.security.MessageDigest;
import java.util.concurrent.ThreadLocalRandom;

/**
 * md5加密工具
 * md5加入随机数进行加密
 */
public class SaltMD5Util {


    /**
     * 生成加盐 md5
     * @param password
     * @return
     */
    public static String generatePassword(String password) {
        //1.生成一个足够长的随机数
        String salt = String.valueOf(ThreadLocalRandom
                .current()
                .nextLong(1000000000000000L, 10000000000000000L));

        //2.将随机数加入明文，生成MD5
        password = md5Hex(password + salt);

        //3.再将随混入生成的MD5码中，方便后期校验明文和秘文
        char[] cs = new char[48];
        for (int i = 0; i < 48; i += 3) {
            cs[i] = password.charAt(i / 3 * 2);
            char c = salt.charAt(i / 3);
            cs[i + 1] = c;
            cs[i + 2] = password.charAt(i / 3 * 2 + 1);
        }

        return new String(cs);
    }

    /**
     * 将明文md5加密后和去盐的md5比对
     * @param password
     * @param md5
     * @return
     */
    public static boolean verifyPassword(String password, String md5) {
        //md5
        char[] cs1 = new char[32];

        //随机数
        char[] cs2 = new char[16];
        //1. 把随机树从md5值中取出
        for (int i = 0; i < 48; i += 3) {
            cs1[i / 3 * 2] = md5.charAt(i);
            cs1[i / 3 * 2 + 1] = md5.charAt(i + 2);
            cs2[i / 3] = md5.charAt(i + 1);
        }
        String salt = new String(cs2);

        //2.把明文密码和随机数再次进行hash 的出来的密文如果一致表示密码正确
        return md5Hex(password + salt).equals(new String(cs1));
    }

    /**
     * 生成md5密码
     * @param src
     * @return
     */
    private static String md5Hex(String src) {
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] bs = md5.digest(src.getBytes());
            return new String(new Hex().encode(bs));
        } catch (Exception e) {
            return "";
        }
    }
}


